package com.zmn.oms.admin.controller.work.modify;

import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.constant.TagConsts;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.dms.common.enums.coup.ThirdPlatEnum;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.common.annotation.PageRequestCas;
import com.zmn.oms.common.constant.OmsErrorCodeConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderPremissionConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.model.dto.fault.FaultItemGroupDTO;
import com.zmn.oms.model.dto.serviceitem.AddOrderServiceItemDTO;
import com.zmn.oms.model.dto.serviceitem.ServiceItemGroupDTO;
import com.zmn.oms.model.dto.serviceitem.TieredTotalPriceDTO;
import com.zmn.oms.model.dto.work.modify.amount.DiscountCouponDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsDiscountDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsUpdateChannelPrepayAmountDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsUpdatePriceDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.model.vo.work.modify.amount.ZsDiscountVO;
import com.zmn.oms.model.vo.work.modify.amount.ZsServiceItemVO;
import com.zmn.oms.model.vo.work.modify.amount.ZsUpdateChannelPrepayAmountVO;
import com.zmn.oms.model.vo.work.modify.amount.ZsUpdatePriceVO;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.orderpay.OrderPayChannelBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkOperatePermissionBService;
import com.zmn.oms.zmn.normal.business.interfaces.discount.ZsNormalOrderDiscountBService;
import com.zmn.oms.zmn.normal.business.interfaces.serviceitem.ZsNormalOrderServiceItemBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.masterwork.ZsNormalMasterWorkBService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 类描述：工单列表操作金额相关controller
 *
 * @author lujia
 * @date 2018/11/07 16:32
 */
@Controller
@RequestMapping("/work/modify")
public class WorkModifyAmountController extends OmsBaseController {

    private Logger logger = LoggerFactory.getLogger(WorkModifyAmountController.class);

    @Autowired
    private ZsNormalMasterWorkBService zsNormalMasterWorkBService;

    @Autowired
    private ZsNormalOrderDiscountBService zsNormalOrderDiscountBService;

    @Autowired
    private ZsNormalOrderServiceItemBService zsNormalOrderServiceItemBService;

    @Autowired
    private OrderWorkService orderWorkService;

    @Autowired
    private ZsOrderWorkOperatePermissionBService orderWorkOperatePermissionBService;

    @Autowired
    private OrderPayChannelBService orderPayChannelBService;

    @Autowired
    private ServItemBService servItemBService;

    /**
     * 改定金
     */
    @GetMapping(value = "/price")
    public ModelAndView price(Long orderId, Long workId) {

        ModelAndView mv = new ModelAndView("work/modify/price");

        ZsUpdatePriceVO updatePriceVO = zsNormalMasterWorkBService.findUpdatePriceVO(orderId, workId);
        List<KVDict<Integer>> codeMap = baseCodeService.getBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, TagConsts.TAG_ONE_TYPE_OMS_UPDATE_PRICE);

        mv.addObject("updatePriceReason", codeMap);
        mv.addObject("updatePriceVO", updatePriceVO);
        return mv;
    }

    /**
     * 改定金实时显示页面内容
     */
    @PostMapping(value = "/find/discount")
    @ResponseBody
    @Deprecated
    public ResultDTO findDiscountListUpdatePrice(@RequestBody ZsUpdatePriceDTO updatePriceDTO) throws OmsBaseException {
        ZsUpdatePriceVO discountVO = zsNormalMasterWorkBService.findDiscountListUpdatePrice(updatePriceDTO);
        return ResultDTO.success(discountVO);
    }

    /**
     * 改定金
     */
    @ResponseBody
    @PostMapping(value = "/save/price")
    public ResultDTO saveUpdatePrice(@RequestBody ZsUpdatePriceDTO updatePriceDTO) throws OmsBaseException {

        // 定金已支付不可修改
        /*OrderWork dbOrderWork = orderWorkService.findOrderWorkByKeySrcMaster(updatePriceDTO.getOrderId(), updatePriceDTO.getWorkId());
        Integer dbDepositAmount = dbOrderWork.getDepositAmount();
        Integer depositAmount = updatePriceDTO.getDepositAmount();
        if (depositAmount != null && !Objects.equals(dbDepositAmount, depositAmount)  && Objects.equals(dbOrderWork.getDepositStatus(), PayConsts.PAY_STATUS_DONE)) {
            return ResultDTO.fail("定金已经支付");
        }*/

        zsNormalMasterWorkBService.saveUpdatePrice(updatePriceDTO);
        return ResultDTO.success();
    }

    /**
     * 渠道预收
     */
    @GetMapping(value = "/channelprepayamount")
    @PageRequestCas(type = OrderConsts.ORDER_OP_TYPE_UPDATE_CHANNEL_PREPAY_AMOUNT)
    public ModelAndView prepayAmount(Long orderId, Long workId) throws OmsBaseException {

        ModelAndView mv = new ModelAndView("work/modify/channelprepayamount");

        ZsUpdateChannelPrepayAmountVO channelPrepayAmountVO = zsNormalMasterWorkBService.findUpdateChannelPrepayAmountVO(orderId, workId);

        /*String test = "京豆,东券";
        if (StringUtil.isNotBlank(test)) {
            List<String> strList = StringUtil.splitStrs(test);
            List<KVDict> result = Lists.newArrayListWithCapacity(strList.size());
            for (int i = 0; i < strList.size(); i++) {
                result.add(KVDict.builder().text(strList.get(i)).value(100).build());
            }
            channelPrepayAmountVO.setChannelPrepayAmountDetailList(result);
        }*/

        mv.addObject("channelPrepayAmountVO", channelPrepayAmountVO);
        return mv;
    }

    /**
     * 保存渠道预收
     */
    @ResponseBody
    @PostMapping(value = "save/channelprepayamount")
    public ResultDTO saveChannelPrepayAmount(@RequestBody ZsUpdateChannelPrepayAmountDTO channelPrepayAmountDTO) {
        try {
            channelPrepayAmountDTO.setIsJudgeOperateAuthority(true);
            zsNormalMasterWorkBService.saveChannelPrepayAmount(channelPrepayAmountDTO);
        } catch (Exception e) {
            return ResultDTO.fail(e.getMessage());
        }
        return ResultDTO.success();
    }

    /**
     * 优惠/验券
     */
    @GetMapping(value = "/discount")
    @PageRequestCas(type = OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE)
    public ModelAndView discount(@RequestParam Long orderId, @RequestParam Long workId, @RequestParam Integer operateId, @RequestParam Integer moduleId) throws Exception {
        if(NumberUtil.isNullOrZero(moduleId)){
            moduleId = OrderPremissionConsts.getModuleIdByPlat(super.getCurrentStaff().getPlat());
        }
        ModelAndView mv;
        // 特殊优惠
        if (Objects.equals(operateId, OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE)) {
            mv = new ModelAndView("work/modify/discountspecial");
        }
        // 人工优惠/验券
        else {
            mv = new ModelAndView("work/modify/discount");
        }

        ZsDiscountVO discountVO = zsNormalOrderDiscountBService.findDiscountVO(orderId, workId, operateId);
        discountVO.setOperateId(operateId);
        //mv.addObject("isMaxDiscount", Objects.equals(operateId, OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE));
        mv.addObject("discountVO", discountVO);
        mv.addObject("moduleId", moduleId);
        return mv;
    }

    /**
     * 保存 人工优惠/验券（后台）
     */
    @PostMapping(value = "/save/discount")
    @ResponseBody
    public ResultDTO saveDiscount(@RequestBody @Valid ZsDiscountDTO discountDTO) throws OmsBaseException {
        boolean couponDiscount = false;
        try {
            logger.debug("人工优惠--->[{}]", discountDTO);
            if (Objects.equals(discountDTO.getDisCategory(), 1) && Objects.equals(discountDTO.getDiscountAmount(), 0)) {
                discountDTO.setRemoveDiscount(GlobalConsts.YES);
            }
            // 是否是验券
            couponDiscount = (Objects.equals(discountDTO.getDisCategory(), ThirdPlatEnum.THIRD_COUP_TYPE_MT.getKey())
                    || Objects.equals(discountDTO.getDisCategory(), ThirdPlatEnum.THIRD_COUP_TYPE_KB.getKey())
                    || Objects.equals(discountDTO.getDisCategory(), ThirdPlatEnum.THIRD_COUP_TYPE_OTHER.getKey()))
                    && StringUtil.isNotBlank(discountDTO.getCouponCode());

            zsNormalOrderDiscountBService.saveArtificialOperator(discountDTO, couponDiscount);
            return ResultDTO.success();
        } catch (OmsBaseException e) {
            logger.error(e.getMessage(), e);
            // 验券失败记录日志
            if (couponDiscount) {
                DiscountCouponDTO couponDTO = BeanMapper.map(discountDTO, DiscountCouponDTO.class);
                Integer thirdPlatEnum = discountDTO.getDisCategory() != null ? discountDTO.getDisCategory() : ThirdPlatEnum.THIRD_COUP_TYPE_OTHER.getKey();
                couponDTO.setRemark(String.format("%s优惠券：%s，%s", ThirdPlatEnum.getValue(thirdPlatEnum), discountDTO.getCouponCode(), StringUtils.defaultIfBlank(e.getMessage(), "优惠券使用失败-未知原因")));
                zsNormalOrderDiscountBService.saveFailCoupon(couponDTO);
            }
            return ResultDTO.fail(e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResultDTO.fail(e.getMessage());
        }
    }

    /**
     * 服务项目
     */
    @GetMapping(value = "/serviceitem")
    @PageRequestCas(type = OrderConsts.ORDER_OP_TYPE_SERVICE_ITEM)
    public ModelAndView serviceitem(Long orderId, Long workId) throws OmsBaseException {

        ModelAndView mv = new ModelAndView("work/modify/serviceitem");

        // 显示服务项
        List<ZsServiceItemVO> serviceItemVOList = zsNormalOrderServiceItemBService.findServiceItemVo(orderId, workId);
        mv.addObject("serviceItemVOList", serviceItemVOList);

        // 是否可以改定金
        OperatePermissionVO supportEditDeposit = orderWorkOperatePermissionBService.getOperatePermission(orderId, workId, OrderConsts.ORDER_OP_TYPE_UPDATE_PRICE);

        // F端不能改定金，控制页面定金文本框可不选。
        if (supportEditDeposit.getCanOperate()){
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
            if (Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)
                    || orderPayChannelBService.onlySupportBankTransfer(orderWork.getBizModeSource(), orderWork.getChannelId())){
                supportEditDeposit.setCanOperate(false);
            }
        }

        // 改价格显示
        ZsUpdatePriceVO updatePriceVO = zsNormalMasterWorkBService.findUpdatePriceVO(orderId, workId);
        logger.debug("updatePriceVO=>[{}]",updatePriceVO);
        List<KVDict<Integer>> codeMap = baseCodeService.getBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, TagConsts.TAG_ONE_TYPE_OMS_UPDATE_PRICE);
        mv.addObject("updatePriceReason", codeMap);
        mv.addObject("updatePriceVO", updatePriceVO);
        mv.addObject("depositEditable", supportEditDeposit.getCanOperate());

        return mv;
    }

    /**
     * 服务项目修改
     */
    @GetMapping(value = "/serviceitem/edit")
    public ModelAndView serviceitemEdit(Long orderId, Long workId, Integer productId, Long proExtId) throws OmsBaseException {
        logger.info("WorkModifyAmountController.serviceitemEdit orderid={}", orderId);
        ModelAndView mv = new ModelAndView("work/modify/serviceitem/edit");

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (!servItemBService.isQuotationType(orderWork.getServItemType())) {
            List<ServiceItemGroupDTO> serviceItemGroupDTOList = zsNormalOrderServiceItemBService.findServiceitemList(orderId, workId, productId);
            mv.addObject("serviceItemGroupDTOList", serviceItemGroupDTOList);
        } else {
            List<FaultItemGroupDTO> serviceItemGroupDTOList = zsNormalOrderServiceItemBService.findFaultItemList(orderId, workId, productId);
            mv.addObject("serviceItemGroupDTOList", serviceItemGroupDTOList);
        }
        List<ZsServiceItemVO> serviceItemVOList = zsNormalOrderServiceItemBService.findServiceItemVo(orderId, workId);
        List<ZsServiceItemVO> collect = serviceItemVOList.stream()
                .filter(serviceItemVO -> Objects.equals(serviceItemVO.getProExtId(), proExtId))
                .collect(Collectors.toList());
        mv.addObject("selectedItem", collect.get(0));
        return mv;
    }

    /**
     * 获取阶梯价金额
     */
    @RequestMapping(value = "/serviceitem/tieredtotalprice")
    @ResponseBody
    public ResultDTO checkDistributeReason(@RequestBody TieredTotalPriceDTO tieredTotalPriceDTO) {
        try {
            Integer tieredTotalPrice = zsNormalOrderServiceItemBService.listTieredTotalPrice(tieredTotalPriceDTO);
            return ResultDTO.success(tieredTotalPrice);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.fail(e.getMessage());
        }
    }

    /**
     * 保存服务项目
     */
    @PostMapping(value = "/save/serviceitem")
    @ResponseBody
    public ResultDTO saveServiceitem(@RequestBody AddOrderServiceItemDTO addOrderServiceItemDTO) {
        try {
            addOrderServiceItemDTO.setQuotationType(GlobalConsts.OPERATE_USER_TYPE_STAFF);
            ResultDTO resultDTO = zsNormalOrderServiceItemBService.saveServiceitem(addOrderServiceItemDTO);
            return resultDTO;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return ResultDTO.fail(e.getMessage());
        }
    }

}
